﻿using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using KdbndpTest.Models;
using SqlSugar;

namespace KdbndpTest.BenchmarkRunner
{
    [MemoryDiagnoser]
    public class Demo3_Queryable
    {
        [Benchmark(Description="查所有")]
        public void QueryableAll()
        {
            var db = GetInstance();
            var getAll = db.Queryable<Order>().ToList();
        }

        [Benchmark(Description = "查询总数")]
        public void QueryableCount()
        {
            var db = GetInstance();
            int count = db.Queryable<Order>().Count();
        }

        [Benchmark(Description = "按条件查询")]
        public void QueryableCondition()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().Where(x=>x.Id==1).ToList();
        }

        [Benchmark(Description = "按多条件查询")]
        public void QueryableMultiConditions()
        {
            var db = GetInstance();

            var orders = db.Queryable<Order>().Where(x => x.Id > 100 && x.Name.Contains("order1")).ToList();
        }

        [Benchmark(Description = "动态Or查询")]
        public void QueryableDynamicOrConditions()
        {
            var db = GetInstance();

            var exp = Expressionable.Create<Order>();

            exp.OrIF(1 == 1, x => x.Id == 10);
            exp.AndIF(true, x => x.Name.Contains("order"));

            var orders = db.Queryable<Order>().Where(exp.ToExpression()).ToList();
        }

        [Benchmark(Description = "根据单主键查询")]
        public void QueryableInSingle()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().Single(x => x.Id == 10);
        }

        [Benchmark(Description = "根据多主键查询")]
        public void QueryableMultiInSingle()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().WhereClassByPrimaryKey(new Order() {Id=10,CustomId=0});
        }

        [Benchmark(Description = "模糊查询")]
        public void QueryableContains()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().Where(x=>x.Name.Contains("order"));
        }

        [Benchmark(Description = "查询最后一条")]
        public void QueryableLast()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>()
                .OrderByDescending(x=>x.Id)
                .First();
        }

        [Benchmark(Description = "查询前几条")]
        public void QueryableTake()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>()
                .Take(100)
                .ToList();
        }

        [Benchmark(Description = "是否存在记录")]
        public void QueryableAny()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>()
                .Any(x => x.Id > 20);
        }

        [Benchmark(Description = "In查询单个字段")]
        public void QueryableIn()
        {
            int[] allIds = new int[] { 10, 11, 12 };

            var db = GetInstance();

            var order = db.Queryable<Order>()
                .Where(x => allIds.Contains(x.Id)).ToList();
        }

        [Benchmark(Description = "In查询多个字段")]
        public void QueryableMultiIn()
        {
            int[] allIds = new int[] { 10, 11, 12 };

            var db = GetInstance();

            var order = db.Queryable<Order>()
                .Where(x => allIds.Contains(x.Id)).ToList();
        }

        [Benchmark(Description = "简单排序")]
        public void QueryableOrderBy()
        {
            var db = GetInstance();

            var getOrderBy = db.Queryable<Order>().OrderBy(it => it.Id, OrderByType.Desc).ToList();
        }

        [Benchmark(Description = "查询最大值")]
        public void QueryableMax()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().Max(it => it.Id);
        }

        [Benchmark(Description = "查询最小值")]
        public void QueryableMin()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().Min(it => it.Id);
        }

        [Benchmark(Description = "求和")]
        public void QueryableSum()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().Sum(it => it.Price);
        }

        [Benchmark(Description = "平均值")]
        public void QueryableAvg()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().Avg(it => it.Price);
        }

        [Benchmark(Description = "查询过滤排除某一个字段")]
        public void QueryableIgnore()
        {
            var db = GetInstance();

            var order = db.Queryable<Order>().IgnoreColumns(it => it.Price).ToList();
        }

        [Benchmark]
        public void 子查询()
        {
            var db = GetInstance();

            var list2 = db.Queryable<Order>().Where(it => SqlFunc.Subqueryable<OrderItem>().Where(i => i.OrderId == it.Id).Any()).ToList();
        }

        [Benchmark]
        public void 分页查询()
        {
            var db = GetInstance();

            var list = db.Queryable<Order>().Take(10).Select(it => new
            {
                customName = SqlFunc.Subqueryable<Custom>().Where("it.CustomId=id").Select(s => s.Name),
                customName2 = SqlFunc.Subqueryable<Custom>().Where("it.CustomId = id").Where(s => true).Select(s => s.Name)
            }).ToList();
        }

        private static SqlSugarClient GetInstance()
        {
            var db = new SqlSugarClient(new ConnectionConfig()
            {
                DbType = SqlSugar.DbType.Kdbndp,
                ConnectionString = Config.ConnectionString,
                InitKeyType = InitKeyType.Attribute,
                IsAutoCloseConnection = true,
                MoreSettings = new ConnMoreSettings()
                {
                    DatabaseModel = DbType.PostgreSQL
                },
                AopEvents = new AopEvents
                {
                    OnLogExecuting = (sql, p) =>
                    {
                        Console.WriteLine(sql);
                        Console.WriteLine(string.Join(",", p?.Select(it => it.ParameterName + ":" + it.Value)));
                    }
                }
            });

            //If no exist create datebase 
            db.DbMaintenance.CreateDatabase();

            //Use db query
            var dt = db.Ado.GetDataTable("select 1");

            //Create tables
            db.CodeFirst.InitTables(typeof(OrderItem), typeof(Order));

            return db;
        }
    }
}
